package smecta.client.print.controller;

import javafx.fxml.FXML;
import javafx.print.Printer;
import javafx.print.PrinterJob;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.RadioButton;
import javafx.scene.control.TextField;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import org.springframework.web.bind.annotation.RestController;

import java.awt.*;
import java.io.*;
import java.util.List;
import java.util.Properties;
import java.util.stream.Collectors;

@RestController
public class BoxSettingController {

    @FXML
    private TextField labelHeight, leftMargin, labelColumns, rightMargin, labelWidth;
    @FXML
    private TextField horizontal, vertical, fontSize;
    @FXML
    private Button savePaperSettingsButton, saveMarginSettingsButton, saveFontSizeButton;
    @FXML
    private Button setPrintableButton, setNonPrintableButton, savePositionButton, closeButton;
    @FXML
    private ComboBox<String> printerSelection, printModeSelection;
    @FXML
    private Button savePrinterSettingsButton, saveFontButton;
    @FXML
    private Pane draggablePane;
    @FXML
    private RadioButton snCol, machineNumCol, boxNumCol, boxWeightCol, canNumCol, canWeightCol, grossWeightCol, netWeightCol, tubeColorCol, dateDayCol,dateTimeCol;


    private Properties properties = new Properties();
    RadioButton focusedTitle=null;
    @FXML
    public void initialize() {
        // ��ʼ���߼���������ش�ӡ��ѡ���
        printModeSelection.getItems().addAll("Font1", "Font2", "Font3");
        makeDraggable(snCol);
        makeDraggable(machineNumCol);
        makeDraggable(boxNumCol);
        makeDraggable(boxWeightCol);
        makeDraggable(canNumCol);
        makeDraggable(canWeightCol);
        makeDraggable(grossWeightCol);
        makeDraggable(netWeightCol);
        makeDraggable(tubeColorCol);
        makeDraggable(dateDayCol);
        makeDraggable(dateTimeCol);

        loadLayout();
        loadTitleNames();
        loadPaperSettings();
        loadPrinterList();
        loadAvailableFonts();
    }
    public  void loadAvailableFonts() {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        String[] fontNames = ge.getAvailableFontFamilyNames();
        printModeSelection.getItems().addAll(fontNames);
    }
    private void loadTitleNames() {
        try (BufferedReader reader = new BufferedReader(new FileReader("./dependencies/db/BoxPrintTitleSet.ini"))) {
            String line;
            while ((line = reader.readLine()) != null) {
                if (line.startsWith("[") && line.endsWith("]")) {
                    String id = line.substring(1, line.length() - 1).trim();
                    String titleName = null;

                    while ((line = reader.readLine()) != null && !line.startsWith("[")) {
                        if (line.startsWith("title=")) {
                            titleName = line.substring("title=".length()).trim();
                            break;
                        }
                    }

                    if (titleName != null) {
                        setRadioButtonText(id, titleName);
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private void loadPrinterList() {
        List<String> printerNames = Printer.getAllPrinters().stream()
                .map(Printer::getName)
                .collect(Collectors.toList());
        printerSelection.getItems().addAll(printerNames);
    }
    private void setRadioButtonText(String id, String text) {
        switch (id) {
            case "snCol":
                snCol.setText(text);
                break;
            case "machineNumCol":
                machineNumCol.setText(text);
                break;
            case "boxNumCol":
                boxNumCol.setText(text);
                break;
            case "boxWeightCol":
                boxWeightCol.setText(text);
                break;
            case "canNumCol":
                canNumCol.setText(text);
                break;
            case "canWeightCol":
                canWeightCol.setText(text);
                break;
            case "grossWeightCol":
                grossWeightCol.setText(text);
                break;
            case "netWeightCol":
                netWeightCol.setText(text);
                break;
            case "tubeColorCol":
                tubeColorCol.setText(text);
                break;
            case "dateDayCol":
                dateDayCol.setText(text);
                break;
            case "dateTimeCol":
                dateTimeCol.setText(text);
                break;
        }
    }

    private void makeDraggable(RadioButton Title) {
        final Delta dragDelta = new Delta();

        Title.setOnMousePressed(mouseEvent -> {
            dragDelta.x = Title.getLayoutX() - mouseEvent.getSceneX();
            dragDelta.y = Title.getLayoutY() - mouseEvent.getSceneY();
            Title.setCursor(javafx.scene.Cursor.MOVE);
            focusedTitle=Title;
        });

        Title.setOnMouseReleased(mouseEvent -> {
            Title.setCursor(javafx.scene.Cursor.HAND);
            setHVText(Title);
        });

        Title.setOnMouseDragged(mouseEvent -> {
            Title.setLayoutX(mouseEvent.getSceneX() + dragDelta.x);
            Title.setLayoutY(mouseEvent.getSceneY() + dragDelta.y);
            setHVText(Title);
        });

        Title.setOnMouseEntered(mouseEvent -> {
            if (!mouseEvent.isPrimaryButtonDown()) {
                Title.setCursor(javafx.scene.Cursor.HAND);
            }
        });

        Title.setOnMouseExited(mouseEvent -> {
            if (!mouseEvent.isPrimaryButtonDown()) {
                Title.setCursor(javafx.scene.Cursor.DEFAULT);
            }
        });
    }

    public void setHVText(RadioButton Title) {
        horizontal.setText("" + Title.getLayoutX());
        vertical.setText("" + Title.getLayoutY());
    }

    public void saveLayout() {
        properties.setProperty("snCol.x", String.valueOf(snCol.getLayoutX()));
        properties.setProperty("snCol.y", String.valueOf(snCol.getLayoutY()));
        properties.setProperty("machineNumCol.x", String.valueOf(machineNumCol.getLayoutX()));
        properties.setProperty("machineNumCol.y", String.valueOf(machineNumCol.getLayoutY()));
        properties.setProperty("boxNumCol.x", String.valueOf(boxNumCol.getLayoutX()));
        properties.setProperty("boxNumCol.y", String.valueOf(boxNumCol.getLayoutY()));
        properties.setProperty("boxWeightCol.x", String.valueOf(boxWeightCol.getLayoutX()));
        properties.setProperty("boxWeightCol.y", String.valueOf(boxWeightCol.getLayoutY()));
        properties.setProperty("canNumCol.x", String.valueOf(canNumCol.getLayoutX()));
        properties.setProperty("canNumCol.y", String.valueOf(canNumCol.getLayoutY()));
        properties.setProperty("canWeightCol.x", String.valueOf(canWeightCol.getLayoutX()));
        properties.setProperty("canWeightCol.y", String.valueOf(canWeightCol.getLayoutY()));
        properties.setProperty("grossWeightCol.x", String.valueOf(grossWeightCol.getLayoutX()));
        properties.setProperty("grossWeightCol.y", String.valueOf(grossWeightCol.getLayoutY()));
        properties.setProperty("netWeightCol.x", String.valueOf(netWeightCol.getLayoutX()));
        properties.setProperty("netWeightCol.y", String.valueOf(netWeightCol.getLayoutY()));
        properties.setProperty("tubeColorCol.x", String.valueOf(tubeColorCol.getLayoutX()));
        properties.setProperty("tubeColorCol.y", String.valueOf(tubeColorCol.getLayoutY()));
        properties.setProperty("dateDayCol.x", String.valueOf(dateDayCol.getLayoutX()));
        properties.setProperty("dateDayCol.y", String.valueOf(dateDayCol.getLayoutY()));
        properties.setProperty("dateTimeCol.x", String.valueOf(dateTimeCol.getLayoutX()));
        properties.setProperty("dateTimeCol.y", String.valueOf(dateTimeCol.getLayoutY()));

        try (OutputStream output = new FileOutputStream("./boxSamplePanel.ini")) {
            properties.store(output, null);
        } catch (IOException io) {
            io.printStackTrace();
        }
    }

    public void loadLayout() {
        try (InputStream input = new FileInputStream("./boxSamplePanel.ini")) {
            properties.load(input);

            snCol.setLayoutX(Double.parseDouble(properties.getProperty("snCol.x", "50")));
            snCol.setLayoutY(Double.parseDouble(properties.getProperty("snCol.y", "30")));
            machineNumCol.setLayoutX(Double.parseDouble(properties.getProperty("machineNumCol.x", "50")));
            machineNumCol.setLayoutY(Double.parseDouble(properties.getProperty("machineNumCol.y", "60")));
            boxNumCol.setLayoutX(Double.parseDouble(properties.getProperty("boxNumCol.x", "50")));
            boxNumCol.setLayoutY(Double.parseDouble(properties.getProperty("boxNumCol.y", "90")));
            boxWeightCol.setLayoutX(Double.parseDouble(properties.getProperty("boxWeightCol.x", "50")));
            boxWeightCol.setLayoutY(Double.parseDouble(properties.getProperty("boxWeightCol.y", "120")));
            canNumCol.setLayoutX(Double.parseDouble(properties.getProperty("canNumCol.x", "50")));
            canNumCol.setLayoutY(Double.parseDouble(properties.getProperty("canNumCol.y", "150")));
            canWeightCol.setLayoutX(Double.parseDouble(properties.getProperty("canWeightCol.x", "50")));
            canWeightCol.setLayoutY(Double.parseDouble(properties.getProperty("canWeightCol.y", "180")));
            grossWeightCol.setLayoutX(Double.parseDouble(properties.getProperty("grossWeightCol.x", "50")));
            grossWeightCol.setLayoutY(Double.parseDouble(properties.getProperty("grossWeightCol.y", "210")));
            netWeightCol.setLayoutX(Double.parseDouble(properties.getProperty("netWeightCol.x", "50")));
            netWeightCol.setLayoutY(Double.parseDouble(properties.getProperty("netWeightCol.y", "240")));
            tubeColorCol.setLayoutX(Double.parseDouble(properties.getProperty("tubeColorCol.x", "50")));
            tubeColorCol.setLayoutY(Double.parseDouble(properties.getProperty("tubeColorCol.y", "270")));
            dateDayCol.setLayoutX(Double.parseDouble(properties.getProperty("dateDayCol.x", "50")));
            dateDayCol.setLayoutY(Double.parseDouble(properties.getProperty("dateDayCol.y", "300")));
            dateTimeCol.setLayoutX(Double.parseDouble(properties.getProperty("dateTimeCol.x", "50")));
            dateTimeCol.setLayoutY(Double.parseDouble(properties.getProperty("dateTimeCol.y", "330")));
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public void savePaperSettings() {
        properties.setProperty("labelHeight", labelHeight.getText());
        properties.setProperty("leftMargin", leftMargin.getText());
        properties.setProperty("labelColumns", labelColumns.getText());
        properties.setProperty("rightMargin", rightMargin.getText());
        properties.setProperty("labelWidth", labelWidth.getText());
        properties.setProperty("printerSelection", printerSelection.getSelectionModel().getSelectedItem());
        properties.setProperty("printModeSelection", printModeSelection.getSelectionModel().getSelectedItem());
        try (OutputStream output = new FileOutputStream("./boxSamplePanel.ini")) {
            properties.store(output, null);
        } catch (IOException io) {
            io.printStackTrace();
        }
    }

    public void loadPaperSettings() {
        try (InputStream input = new FileInputStream("./boxSamplePanel.ini")) {
            properties.load(input);

            labelHeight.setText(properties.getProperty("labelHeight", "0"));
            leftMargin.setText(properties.getProperty("leftMargin", "0"));
            labelColumns.setText(properties.getProperty("labelColumns", "0"));
            rightMargin.setText(properties.getProperty("rightMargin", "0"));
            labelWidth.setText(properties.getProperty("labelWidth", "0"));
            fontSize.setText(properties.getProperty("fontSize", "0"));
            printerSelection.getSelectionModel().select(properties.getProperty("printerSelection", ""));
            printModeSelection.getSelectionModel().select(properties.getProperty("printModeSelection", ""));
            updateRadioButtonColor(snCol);
            updateRadioButtonColor(machineNumCol);
            updateRadioButtonColor(boxNumCol);
            updateRadioButtonColor(boxWeightCol);
            updateRadioButtonColor(canNumCol);
            updateRadioButtonColor(canWeightCol);
            updateRadioButtonColor(grossWeightCol);
            updateRadioButtonColor(netWeightCol);
            updateRadioButtonColor(tubeColorCol);
            updateRadioButtonColor(dateDayCol);
            updateRadioButtonColor(dateTimeCol);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
    private void updateRadioButtonColor(RadioButton radioButton) {
        String printable = properties.getProperty(radioButton.getId() + ".printable", "false");
        if ("true".equals(printable)) {
            radioButton.setStyle("-fx-background-color: green;");
        } else {
            radioButton.setStyle("-fx-background-color: red;");
        }
    }

    @FXML
    private void handlePrint() {
        PrinterJob job = PrinterJob.createPrinterJob();
        if (job != null && job.showPrintDialog(this.draggablePane.getScene().getWindow())) {
            boolean success = job.printPage(this.draggablePane);
            if (success) {
                job.endJob();
            }
        }
    }

    private class Delta {
        double x, y;
    }

    @FXML
    private void handleSavePaperSettings() {
        savePaperSettings();
        System.out.println("handleSavePaperSettings");
    }


    @FXML
    private void handleSaveFontSize() {
        System.out.println("focusedTitle:"+focusedTitle);
        if (focusedTitle != null) {
            properties.setProperty(focusedTitle.getId() +  ".fontSize", fontSize.getText());
            saveProperties();
            System.out.println("���������С"+focusedTitle.getId());
        }

    }

    @FXML
    private void handleSetPrintable() {
        System.out.println("focusedTitle:"+focusedTitle);
        if (focusedTitle != null) {
            properties.setProperty(focusedTitle.getId() + ".printable", "true");
            saveProperties();
            focusedTitle.setStyle("-fx-background-color: green;");
        }
        System.out.println("���ÿɴ�");
    }

    @FXML
    private void handleSetNonPrintable() {
        System.out.println("focusedTitle:"+focusedTitle);
        if (focusedTitle != null) {
            properties.setProperty(focusedTitle.getId() + ".printable", "false");
            saveProperties();
            focusedTitle.setStyle("-fx-background-color: red;");
        }
        System.out.println("���ò���");
    }

    @FXML
    private void handleSavePosition() {
        saveLayout();
        System.out.println("����λ��");
    }

    @FXML
    private void handleClose() {
        // �رմ���
        Stage stage = (Stage) closeButton.getScene().getWindow();
        stage.close();
    }

    @FXML
    private void handleSaveSettings() {
        saveLayout();
        savePaperSettings();
        System.out.println("�����ӡ������");
    }

    @FXML
    private void handleSaveFont() {
        savePaperSettings();
        System.out.println("������������");
    }

    private RadioButton getSelectedRadioButton() {
        return focusedTitle;
    }
    private void saveProperties() {
        try (OutputStream output = new FileOutputStream("./boxSamplePanel.ini")) {
            properties.store(output, null);
        } catch (IOException io) {
            io.printStackTrace();
        }
    }

}
